package com.culturalCenter.dataCenter.service.impl.site;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.culturalCenter.dataCenter.Utils.DateFormatUtil;
import com.culturalCenter.dataCenter.Utils.TimeUtil;
import com.culturalCenter.dataCenter.customEntity.responseParam.site.SiteInfoResponse;
import com.culturalCenter.dataCenter.customEntity.responseParam.site.SiteListResponse;
import com.culturalCenter.dataCenter.customEntity.responseParam.site.SiteMenuResponse;
import com.culturalCenter.dataCenter.customEntity.responseParam.site.SiteStatusResponse;
import com.culturalCenter.dataCenter.customEntity.site.CustomSite;
import com.culturalCenter.dataCenter.customEntity.site.CustomSiteBooking;
import com.culturalCenter.dataCenter.customEntity.site.CustomSiteUsedCount;
import com.culturalCenter.dataCenter.entity.site.Site;
import com.culturalCenter.dataCenter.entity.site.SiteUsedCount;
import com.culturalCenter.dataCenter.mapper.site.*;
import com.culturalCenter.dataCenter.param.DateParam;
import com.culturalCenter.dataCenter.service.site.SiteService;
import com.culturalCenter.dataCenter.vo.SiteUsedDataVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import scala.annotation.meta.param;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;

/**
 * Site业务层接口实现类
 */
@Service
public class SiteServiceImpl implements SiteService {

    @Resource
    private SiteMapper siteMapper;
    @Resource
    private SiteBookingMonthMapper siteBookingMonthMapper;
    @Resource
    private SiteBookingMapper siteBookingMapper;
    @Resource
    private SiteUsedCountMapper siteUsedCountMapper;
    @Resource
    private SiteAlertsMapper  siteAlertsMapper;

    @Override
    public PageInfo<Site> findPage(int page, int size) {
        return PageHelper.startPage(page, size).doSelectPageInfo(() -> siteMapper.findPageAll());
    }

    @Override
    public Integer delete(String id) {
        return siteMapper.deleteById(id);
    }

    @Override
    public Integer update(Site site) {
        return siteMapper.update(site);
    }

    @Override
    public Integer add(Site site) {
        return siteMapper.insert(site);
    }

    @Override
    public Site findById(String id) {
        return siteMapper.queryById(id);
    }

    @Override
    public List<Site> findAll(Site site) {
        return (List<Site>) siteMapper.queryAll(site);
    }

    @Override
    public List<String> getSiteArea() {
        return siteMapper.getSiteArea();
    }

    @Override
    public SiteStatusResponse getSiteStatus() {
        SiteStatusResponse siteStatusResponse = new SiteStatusResponse();
        // 统计
        Integer total = siteMapper.selectTotal();
        Integer usedSites = siteBookingMapper.selectCountByStatus(3, new Date());
        siteStatusResponse.setTotal(total);
        siteStatusResponse.setUsedSites(usedSites);
        siteStatusResponse.setUnusedSites(total - usedSites);
        // 列表
        // 获取片区
        Map<String, List<CustomSiteBooking>> siteMap = new HashMap<>();
        List<String> areaList = getSiteArea();
        // 查场地
        if (CollectionUtils.isNotEmpty(areaList)) {
            areaList.forEach(area -> {
                if (StrUtil.isNotEmpty(area)) {
                    siteMap.put(area, siteMapper.findSiteStatusByArea(area, new Date()));
                }
            });
        }
        siteStatusResponse.setSiteMap(siteMap);
        return siteStatusResponse;
    }

    @Override
    public SiteStatusResponse searchSiteStatus(Date startTime, Date endTime) {
        SiteStatusResponse siteStatusResponse = new SiteStatusResponse();
        // 统计
        Integer total = siteMapper.selectTotal();
//        Integer usedSites1 = siteBookingMapper.searchCountByStatus(4, startTime, endTime);
        Integer usedSites = siteBookingMapper.newSearchCountByStatus(startTime, endTime);
        siteStatusResponse.setTotal(total);
        siteStatusResponse.setUsedSites(usedSites);
        siteStatusResponse.setUnusedSites(total - usedSites);
        // 列表
        // 获取片区
        Map<String, List<CustomSiteBooking>> siteMap = new HashMap<>();
        List<String> areaList = getSiteArea();
        // 查场地
        if (CollectionUtils.isNotEmpty(areaList)) {
            areaList.forEach(area -> {
                if (StrUtil.isNotEmpty(area)) {
                    List<CustomSiteBooking> customSiteBookings = siteMapper.searchSiteStatusByArea(area, startTime, endTime);
                    if (!isWithinTimeRange(startTime,endTime)){
                    for (CustomSiteBooking customSiteBooking : customSiteBookings) {
                        customSiteBooking.setTiming(-1);
                    }}
                    siteMap.put(area, customSiteBookings);
                }
            });
        }
        siteStatusResponse.setSiteMap(siteMap);
        return siteStatusResponse;
    }
    private boolean isWithinTimeRange(Date startTime,Date endTime){
        Date date = new Date();
        return date.after(startTime)&& date.before(endTime);
    }

    @Override
    public SiteStatusResponse searchSiteStatusAfter(Date startTime, Date endTime) {
        SiteStatusResponse siteStatusResponse = new SiteStatusResponse();
        // 统计
        Integer total = siteMapper.selectTotal();
        Integer usedSites1 = siteBookingMapper.searchCountByStatus(1, startTime, endTime);
        Integer usedSites5 = siteBookingMapper.searchCountByStatus(5, startTime, endTime);
        siteStatusResponse.setTotal(total);
        siteStatusResponse.setUsedSites(usedSites1 + usedSites5);
        siteStatusResponse.setUnusedSites(total - usedSites1 - usedSites5);
        // 列表
        // 获取片区
        Map<String, List<CustomSiteBooking>> siteMap = new HashMap<>();
        List<String> areaList = getSiteArea();
        // 查场地
        if (CollectionUtils.isNotEmpty(areaList)) {
            areaList.forEach(area -> {
                if (StrUtil.isNotEmpty(area)) {
                    List<CustomSiteBooking> customSiteBookings = siteMapper.searchSiteStatusByAreaAfter(area, startTime, endTime);
                    for (CustomSiteBooking customSiteBooking : customSiteBookings) {
                        customSiteBooking.setTiming(1);
                    }
                    siteMap.put(area, customSiteBookings);
                }
            });
        }
        siteStatusResponse.setSiteMap(siteMap);
        return siteStatusResponse;
    }

    @Override
    public SiteListResponse getSiteList(String siteName, String siteType, int pageNum, int pageSize) {
        SiteListResponse siteListResponse = new SiteListResponse();

        Integer total = siteMapper.selectTotal();
        siteListResponse.setTotal(total);
        Integer usedSites = siteBookingMapper.selectCountByStatus(3, new Date());
        siteListResponse.setUsedSites(usedSites);
        siteListResponse.setUnusedSites(total - usedSites);

        // 场地类型列表
        List<String> siteTypeList = siteMapper.getSiteTypeList();
        if (CollectionUtil.isNotEmpty(siteTypeList)) {
            siteTypeList.removeIf(StrUtil::isEmpty);
            siteListResponse.setSiteTypeList(siteTypeList);
        }
        // 符合条件的场地数量?
        siteListResponse.setNum(siteMapper.countByNameAndType(siteName, siteType));

        PageHelper.startPage(pageNum, pageSize);
        // 场地列表
        List<CustomSite> siteList = siteMapper.selectCustomSite(siteName, siteType);
        if (CollectionUtils.isNotEmpty(siteList)) {
            siteListResponse.setSiteList(siteList);
        }
        PageHelper.clearPage();
        return siteListResponse;
    }

    @Override
    public SiteInfoResponse getSiteInfo(String siteCode, int size) {
        // 基本信息
        SiteInfoResponse siteInfoResponse = siteMapper.selectSiteInfo(siteCode);
        //siteCode拿booking的id
        String siteBookingId = siteMapper.getSiteIdBySiteCode(siteCode);
        // 本月统计信息
        CustomSiteUsedCount customSiteUsedCount = siteUsedCountMapper.selectSiteInfoCount(siteCode);
        if (customSiteUsedCount != null) {
            siteInfoResponse.setServeNum(customSiteUsedCount.getServeNum());
            siteInfoResponse.setServeHours(customSiteUsedCount.getServeHours());
            siteInfoResponse.setBookingNum(customSiteUsedCount.getBookingNum());
            siteInfoResponse.setOutsiderNum(customSiteUsedCount.getOutsiderNum());
            siteInfoResponse.setInsiderNum(customSiteUsedCount.getInsiderNum());
            siteInfoResponse.setTotal(customSiteUsedCount.getTotal());
            siteInfoResponse.setUnusedDays(customSiteUsedCount.getUnusedDays());
            siteInfoResponse.setUsedRate(customSiteUsedCount.getUsedRate());
        }

        if (Objects.isNull(siteInfoResponse)) {
            siteInfoResponse = new SiteInfoResponse();
        }

        Integer status = siteBookingMapper.selectStatusBySiteId(siteCode);
        // 场地当前状态。为null返回0，剩下是什么状态就返回什么状态
        siteInfoResponse.setStatus((status != null) ? status : 0);

        // 本月场地预约柱状图
        int startDate = 1, endDate = size;
        Map<String, Integer> bookingMonthMap = new LinkedHashMap<>();
        while (endDate <= 31) {
            // 横坐标格式化作为key
            String key = (startDate < 10 ? "0" : "") + startDate + "-" + (endDate < 10 ? "0" : "") + endDate;
            // 得到该区间的预约次数
            bookingMonthMap.put(key, siteBookingMonthMapper.selectSiteInfoBookingCountByDate(siteCode, startDate, endDate));
            startDate += size;
            endDate += size;
        }
        // while循环后startDate为29，得到29到该月最后一天的预约数
        bookingMonthMap.put(startDate + "-" + DateFormatUtil.getLastDayByDate(new Date()), siteBookingMonthMapper.selectSiteInfoBookingCountByDate(siteBookingId, startDate, 31));
        siteInfoResponse.setBookingCountMap(bookingMonthMap);

        Integer signInNum = siteBookingMapper.selectSignInNum(siteBookingId);
        siteInfoResponse.setSignInNum(signInNum);
        Integer noSignInNum = siteBookingMapper.selectNoSignInNum(siteBookingId);
        siteInfoResponse.setNoSignInNum(noSignInNum);
        return siteInfoResponse;
    }

    @Override
    public String getSiteIdBySiteCode(String siteCode) {
        return siteMapper.getSiteIdBySiteCode(siteCode);
    }

    @Override
    public SiteMenuResponse getSiteMenu(DateParam param) {
        SiteMenuResponse siteMenuResponse = new SiteMenuResponse();
        Integer usedSites = siteBookingMapper.selectCountByStatus(3, new Date());
        siteMenuResponse.setUsedSites(usedSites);
        Integer total = siteMapper.selectTotal();
        siteMenuResponse.setTotal(total);

        Map<String, Map<String, Integer>> siteBookingTimeCountMap = new HashMap<>();
        List<String> siteTypeList = siteMapper.getSiteTypeList();
        String startDate = null;
        String endDate = null;
        if (param.getYear() != null) {
            Map<String, String> yearMap = TimeUtil.getTimeMap(param.getYear(), "year");
            startDate = yearMap.get("start");
            endDate = yearMap.get("end");
        }
        if (param.getMonth() != null) {
            Map<String, String> yearMap = TimeUtil.getTimeMap(param.getMonth(), "month");
            startDate = yearMap.get("start");
            endDate = yearMap.get("end");
        }
        if (param.getDay() != null) {
            Map<String, String> dayMap = TimeUtil.getTimeMap(param.getDay(), "day");
            startDate = dayMap.get("start");
            endDate = dayMap.get("end");
        }
        //查询的场地预约时段分析
//        startDate = DateFormatUtil.getOfMonth(LocalDateTime.now(), null);
//        endDate = DateFormatUtil.getOfMonth(LocalDateTime.now(), "end");
        for (String siteType : siteTypeList) {
            if (!StringUtils.isEmpty(siteType) && !siteType.trim().equals("其他")) {
                Map<String, Integer> timeMap = new LinkedHashMap<>();
                timeMap.put("09:00~12:00", siteBookingMapper.countBookingNumByCategoryAndTime(siteType, "09", "12", startDate, endDate));
                timeMap.put("14:00~17:00", siteBookingMapper.countBookingNumByCategoryAndTime(siteType, "14", "17", startDate, endDate));
                timeMap.put("18:00~21:00", siteBookingMapper.countBookingNumByCategoryAndTime(siteType, "18", "21", startDate, endDate));
//                        timeMap.put("15:00~18:00", siteBookingMapper.countBookingNumByCategoryAndTime(siteType, "15", "18",startDate,endDate));
//                        timeMap.put("18:00~24:00", siteBookingMapper.countBookingNumByCategoryAndTime(siteType, "18", "24",startDate,endDate));
                siteBookingTimeCountMap.put(siteType, timeMap);
            } else {
                Map<String, Integer> timeMap1 = new LinkedHashMap<>();
                timeMap1.put("09:00~12:00", siteBookingMapper.countBookingNumByCategoryIsOtherAndTime("09", "12", startDate, endDate));
                timeMap1.put("14:00~17:00", siteBookingMapper.countBookingNumByCategoryIsOtherAndTime("14", "17", startDate, endDate));
                timeMap1.put("18:00~21:00", siteBookingMapper.countBookingNumByCategoryIsOtherAndTime("18", "21", startDate, endDate));
//                timeMap1.put("", siteBookingMapper.countBookingNumByCategoryIsOtherAndTime("15", "18",startDate,endDate));
//                timeMap1.put("", siteBookingMapper.countBookingNumByCategoryIsOtherAndTime("18", "24",startDate,endDate));
                siteBookingTimeCountMap.put("其他", timeMap1);
            }
            siteMenuResponse.setSiteBookingTimeCountMap(siteBookingTimeCountMap);

        }

        Map<String, String> openTypeMap = new HashMap<>();
        List<String> siteOpenTypeList = siteMapper.getSiteOpenTypeList();
        if (CollectionUtils.isNotEmpty(siteOpenTypeList)) {
            siteOpenTypeList.forEach(openType -> {
                if (StrUtil.isNotEmpty(openType)) {
                    openTypeMap.put(openType.equals("1") ? "不限制" : openType.equals("2") ? "对外开放场地" : "对内开放场地", siteMapper.countByOpenType(openType));
                    siteMenuResponse.setOpenTypeMap(openTypeMap);
                }
            });
        }

        Map<String, String> siteTypeMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(siteTypeList)) {
            siteTypeList.forEach(type -> {
                if (StrUtil.isNotEmpty(type) && !type.trim().equals("其他")) {
                    siteTypeMap.put(type, siteMapper.countBySiteType(type));
                    siteMenuResponse.setSiteTypeMap(siteTypeMap);
                }
            });
            //“其他”类型的数量包括类型为其他和为空两种加起来的数量
            int otherCount = siteMapper.countBySiteTypeIsOther();
            if (otherCount != 0) {
                siteTypeMap.put("其他", Integer.toString(siteMapper.countBySiteTypeIsOther()));
            }
        }
        return siteMenuResponse;
    }

    @Override
    public SiteUsedDataVo getSiteUsedData(String siteCode, Date startDate, Date endDate) {
        if (startDate == null || endDate == null){
            startDate = Timestamp.valueOf(LocalDateTime.of(LocalDate.now().withDayOfMonth(1), LocalTime.MIN));
            endDate = Timestamp.valueOf(LocalDateTime.now());
        }
        SiteUsedDataVo vo =  siteMapper.getSiteUsedData(siteCode,startDate,endDate);
        if (vo == null)
            vo = new SiteUsedDataVo();
        String siteId = siteMapper.selectSiteIdBySiteCode(siteCode);
        Integer alertsNum = siteAlertsMapper.countAlertsNumBySiteId(siteId, startDate, endDate);
        vo.setAlertsNum(alertsNum);
        return vo;
    }

}
